package dev.ece.suit.loader.models.ms3d;

import java.io.IOException;

import dev.ece.util.io.LittleEndianInputStream;
import dev.ece.util.lib.Vector3f;
import dev.ece.util.lib.Vector4f;

/**
 * 顶点信息
 * @author 飘渺青衣
 * <b>E-mail：</b>3375758@qq.com
 */
public class MS3DVertex extends Vector3f {

	private Vector4f boneIds = new Vector4f();
	
	private Vector4f weights = new Vector4f(1.0f, 0.0f, 0.0f, 0.0f);
	
	private MS3DVertex() {}
	
	private void setWeights(int w1, int w2, int w3) {
		int sum = w1 + w2 + w3;
		if(sum > 0) {
			weights.set(w1 / 100f, w2 / 100f, w3 / 100f, (100 - sum) / 100f);
		}
	}
	
	public static MS3DVertex[] load(LittleEndianInputStream is) throws IOException {
		MS3DVertex[] vertice = new MS3DVertex[is.readUnsignedShort()];
		MS3DVertex vertex = null;
		for(int i=0; i<vertice.length; i++) {
			vertice[i] = vertex = new MS3DVertex();
			is.skip(1);
			vertex.set(is.readFloat(), is.readFloat(), is.readFloat());
			vertex.boneIds.setX(is.readByte());
			is.skip(1);
		}
		return vertice;
	}
	
	public static Vector3f[] boundBox(MS3DVertex[] vertice) {
		Vector3f[] boxs = new Vector3f[2];
		if(vertice != null && vertice.length > 0) {
			Vector3f box = null;
			boxs[0] = new Vector3f(vertice[0]);
			boxs[1] = new Vector3f(vertice[0]);
			for(MS3DVertex vertex: vertice) {
				box = boxs[0];
				box.set(Math.min(vertex.getX(), box.getX()), 
						Math.min(vertex.getY(), box.getY()), 
						Math.min(vertex.getZ(), box.getZ()));
				box = boxs[1];
				box.set(Math.max(vertex.getX(), box.getX()), 
						Math.max(vertex.getY(), box.getY()), 
						Math.max(vertex.getZ(), box.getZ()));
			}
		}
		return boxs;
	}
	
	/**
	 * 额外信息
	 * @param is
	 * @param vertice
	 * @throws IOException
	 */
	public static void loadExtra(LittleEndianInputStream is, MS3DVertex[] vertice) throws IOException {
		if(is.available() > 0) {
			int subVersion = is.readInt();
			boolean isExtra = subVersion == 2;
			if(subVersion == 2 || subVersion == 1) {
				MS3DVertex vertex = null;
				for(int i=0; i<vertice.length; i++) {
					vertex = vertice[i];
					vertex.boneIds.setY(is.readByte());
					vertex.boneIds.setZ(is.readByte());
					vertex.boneIds.setW(is.readByte());
					vertex.setWeights(is.readUnsignedChar(), is.readUnsignedChar(), is.readUnsignedChar());
					if(isExtra) {
						is.skip(4);
					}
				}
			}
		}
	}
	
	protected Vector4f getBoneIds() {
		return boneIds;
	}

	protected Vector4f getWeights() {
		return weights;
	}
	
}
